package coupon

import (
	"bp/internal/render"
	"bp/internal/service/entity/coupon"
	"bp/internal/service/param"
	"bp/internal/util"
	couponGrpc "bp/rpc/gen/mwebapi/mcoupon"
	"context"
)

func (s *CouponMWebApiImp) GetCoupon(ctx context.Context, req *couponGrpc.GetCouponReq) (res *couponGrpc.GetCouponRes, err error) {
	slog := util.NewContextLogger(ctx, s.slog)
	slog.Infof("coupon_imp/query.GetCoupon=>%+v", req)
	defer render.FriendlyEntityError(&err, EntityName)
	res = &couponGrpc.GetCouponRes{}
	q := s.dao.Q

	couponPtr, available, err := s.VldGetCouponReq(ctx, q, req)
	if err != nil {
		return
	}
	couponID := couponPtr.ID
	itemCategoryConfPtrs, err := s.entityHub.CouponService.ListItemCategoryConfigurationPtrsByCouponID(ctx, q, couponID)
	if err != nil {
		return
	}
	itemConfPtrs, err := s.entityHub.CouponService.ListItemConfigurationPtrsByCouponID(ctx, q, couponID)
	if err != nil {
		return
	}
	res.Coupon = s.ConvCouponPtrEntityToPb(itemCategoryConfPtrs, itemConfPtrs)(couponPtr)
	res.Available = available
	return
}

func (s *CouponMWebApiImp) GetMemberCoupon(ctx context.Context, req *couponGrpc.GetMemberCouponReq) (res *couponGrpc.GetMemberCouponRes, err error) {
	slog := util.NewContextLogger(ctx, s.slog)
	slog.Infof("coupon_imp/query.GetMemberCoupon=>%+v", req)
	defer render.FriendlyEntityError(&err, EntityName)
	res = &couponGrpc.GetMemberCouponRes{}
	q := s.dao.Q

	memberCouponID, err := s.VldGetMemberCouponReq(ctx, q, req)
	if err != nil {
		return
	}
	memberCouponPtr, err := s.entityHub.MemberCouponService.GetMemberCouponPtr(ctx, q, memberCouponID)
	if err != nil {
		return
	}
	couponID := memberCouponPtr.CouponID
	itemCategoryConfPtrs, err := s.entityHub.CouponService.ListItemCategoryConfigurationPtrsByCouponID(ctx, q, couponID)
	if err != nil {
		return
	}
	itemConfPtrs, err := s.entityHub.CouponService.ListItemConfigurationPtrsByCouponID(ctx, q, couponID)
	if err != nil {
		return
	}
	couponPtr, err := s.entityHub.CouponService.GetCouponPtr(ctx, q, couponID)
	if err != nil {
		return
	}
	res.MemberCoupon = s.ConvMemberCouponPtrEntityToPb(itemCategoryConfPtrs, itemConfPtrs, couponPtr)(memberCouponPtr)
	return
}

func (s *CouponMWebApiImp) ListCouponWithDistributionStats(ctx context.Context, req *couponGrpc.ListCouponWithDistributionStatsReq) (res *couponGrpc.ListCouponWithDistributionStatsRes, err error) {
	slog := util.NewContextLogger(ctx, s.slog)
	slog.Infof("coupon_imp/query.ListCouponWithDistributionStats=>%+v", req)
	defer render.FriendlyEntityError(&err, EntityName)
	res = &couponGrpc.ListCouponWithDistributionStatsRes{}
	q := s.dao.Q

	cPtr := param.GenListCommonParamFromContext(ctx)
	ptr, err := s.VldListCouponWithDistributionStatsReq(ctx, q, req)
	if err != nil {
		return
	}
	total, couponWithDistributionStatPtrs, err := s.entityHub.CouponService.ListCouponWithDistributionStatPtrs(ctx, q, cPtr, ptr)
	if err != nil {
		return
	}
	var itemCategoryMap param.EntityIDToItemCategoryConfigurationPtrsMap
	var itemMap param.EntityIDToItemConfigurationPtrsMap

	res.Total = int32(total)
	res.Rows = s.ConvCouponWithDistributionStatPtrArrayEntityToPb(itemCategoryMap, itemMap)(couponWithDistributionStatPtrs)
	return
}

func (s *CouponMWebApiImp) ListMemberCoupons(ctx context.Context, req *couponGrpc.ListMemberCouponsReq) (res *couponGrpc.ListMemberCouponsRes, err error) {
	slog := util.NewContextLogger(ctx, s.slog)
	slog.Infof("coupon_imp/query.ListMemberCoupons=>%+v", req)
	defer render.FriendlyEntityError(&err, EntityName)
	res = &couponGrpc.ListMemberCouponsRes{}
	q := s.dao.Q

	cPtr := param.GenListCommonParamFromContext(ctx)
	ptr, err := s.VldListMemberCouponsReq(ctx, q, req)
	if err != nil {
		return
	}
	total, memberCouponPtrs, err := s.entityHub.MemberCouponService.ListMemberCouponPtrs(ctx, q, cPtr, ptr)
	if err != nil {
		return
	}

	var itemCategoryMap param.EntityIDToItemCategoryConfigurationPtrsMap
	var itemMap param.EntityIDToItemConfigurationPtrsMap
	var couponMap coupon.CouponIDToCouponPtrMap
	if len(memberCouponPtrs) > 0 && (req.WithItemCategoryConfs || req.WithItemConfs) {
		couponIDs := s.ConvMemberCouponPtrsToCouponIDs(memberCouponPtrs)
		if req.WithItemCategoryConfs {
			itemCategoryMap, err = s.entityHub.CouponService.GetMapOfCouponIDToItemCategoryConfigurationPtrsByCouponIDs(ctx, q, couponIDs)
			if err != nil {
				return
			}
		}
		if req.WithItemConfs {
			itemMap, err = s.entityHub.CouponService.GetMapOfCouponIDToItemConfigurationPtrsByCouponIDs(ctx, q, couponIDs)
			if err != nil {
				return
			}
		}
		couponMap, err = s.entityHub.CouponService.GetMapOfCouponIDToCouponPtrByCouponIDs(ctx, q, couponIDs)
		if err != nil {
			return
		}
	}
	res.Total = int32(total)
	res.Rows = s.ConvMemberCouponPtrArrayEntityToPb(itemCategoryMap, itemMap, couponMap)(memberCouponPtrs)
	return
}

// 列出可用的促销活动
func (s *CouponMWebApiImp) ListAvailableMemberCoupons(ctx context.Context, req *couponGrpc.ListAvailableMemberCouponsReq) (res *couponGrpc.ListAvailableMemberCouponsRes, err error) {
	slog := util.NewContextLogger(ctx, s.slog)
	slog.Infof("promotion_imp/query.ListAvailableMemberCoupons=>%+v", req)
	defer render.FriendlyEntityError(&err, EntityName)
	res = &couponGrpc.ListAvailableMemberCouponsRes{}
	q := s.dao.Q

	ptr, err := s.VldListAvailableMemberCouponsReq(ctx, q, req)
	if err != nil {
		return
	}
	memberCouponPtrs, err := s.entityHub.MemberCouponService.ListAvailableMemberCouponsOfUseScene(ctx, q, ptr)
	if err != nil {
		return
	}

	var itemCategoryMap param.EntityIDToItemCategoryConfigurationPtrsMap
	var itemMap param.EntityIDToItemConfigurationPtrsMap
	var couponMap coupon.CouponIDToCouponPtrMap
	if len(memberCouponPtrs) > 0 && (req.WithItemCategoryConfs || req.WithItemConfs) {
		couponIDs := s.ConvMemberCouponPtrsToCouponIDs(memberCouponPtrs)
		if req.WithItemCategoryConfs {
			itemCategoryMap, err = s.entityHub.CouponService.GetMapOfCouponIDToItemCategoryConfigurationPtrsByCouponIDs(ctx, q, couponIDs)
			if err != nil {
				return
			}
		}
		if req.WithItemConfs {
			itemMap, err = s.entityHub.CouponService.GetMapOfCouponIDToItemConfigurationPtrsByCouponIDs(ctx, q, couponIDs)
			if err != nil {
				return
			}
		}
		couponMap, err = s.entityHub.CouponService.GetMapOfCouponIDToCouponPtrByCouponIDs(ctx, q, couponIDs)
		if err != nil {
			return
		}
	}

	res.MemberCoupons = s.ConvMemberCouponPtrArrayEntityToPb(itemCategoryMap, itemMap, couponMap)(memberCouponPtrs)
	return
}
